package com.ym.medical.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ym.common.utils.HttpUtil;


import com.ym.common.utils.HuaWeiHttpUtil;
import com.ym.core.rabbit.IMessageSenderSV;
import com.ym.medical.dao.InquiryOrderDao;
import com.ym.medical.domain.entity.AxbResultEntity;
import com.ym.medical.domain.param.InquiryOrderParam;
import com.ym.medical.domain.vo.OrderAndFileVO;
import com.ym.medical.domain.vo.PhoneInfoVo;
import com.ym.medical.enums.FileTypeEnum;
import com.ym.medical.service.IAxbResultSV;
import com.ym.medical.service.IDoctorSV;
import com.ym.medical.service.IFileInforSV;
import com.ym.medical.service.task.BindPhoneTask;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author 文博
 * @create 2019-04-30 16:09
 **/
@Service
@Transactional(rollbackFor = Exception.class)
public class DoctorSVImpl implements IDoctorSV {


	private org.slf4j.Logger logger = LoggerFactory.getLogger(DoctorSVImpl.class);

	/**
	 * 必填,请登录管理控制台,从"应用管理"页获取
	 */

	/**
	 * APP_Key
	 */

	private static final String OMPAPPKEY = "e08pjcC07W6q09SOrEIoOrcD3OXp";
	/**
	 * APP_Secret
	 */

	private static final String OMPAPPSECRET = "wjy6YLvH4Qrv0Y80C373TGEbQ6j7";
	/**
	 * APP接入地址
	 */

	private static final String OMPDOMAINNAME = "https://rtcapi.cn-north-1.myhuaweicloud.com:12543";


	@Autowired
	private InquiryOrderDao inquiryOrderDao;

	@Autowired
	private IAxbResultSV iAxbResultSV;

	@Autowired
	private IMessageSenderSV messageSenderSV;

	@Autowired
	private DoctorServiceItemSVImpl doctorServiceItemImpl;

	@Autowired
	private IFileInforSV iFileInforSV;


	/**
	 * Build the real url of https request | 构建隐私保护通话平台请求路径
	 *
	 * @param path 接口访问URI
	 * @return
	 */
	private String buildOmpUrl(String path) {
		return OMPDOMAINNAME + path;
	}

	/**
	 * 隐私号码AXB绑定
	 *
	 * @param //relationNum 关系号码
	 * @param //callerNum   主叫号码
	 * @param //calleeNum   被叫号码
	 */
	@Override
	public void axbBindNumber() throws ParseException {
//        if (StringUtils.isBlank(callerNum) || StringUtils.isBlank(calleeNum)) {
//            logger.info("axbBindNumber set params error");
//            return;
//        }

		//必填,AXB模式绑定接口访问URI
		String url = "/rest/caas/relationnumber/partners/v1.0";
		String realUrl = buildOmpUrl(url);
		/*
		 *查询订单中电话预约列表
		 * 患者电话 医生电话 通话时长
		 */
		// 封装JOSN请求
		JSONObject json = new JSONObject();
		List<PhoneInfoVo> phoneInfoVos = inquiryOrderDao.selectPhoneInfo();
		if (phoneInfoVos.isEmpty() || phoneInfoVos.size() == 0) {
			return;
		}
		for (PhoneInfoVo phoneInfoVo : phoneInfoVos) {
			//json.put("relationNum", relationNum); // X号码(关系号码)
			// A方真实号码(手机或固话)
			json.put("callerNum", phoneInfoVo.getDoctPhone());
			// B方真实号码(手机或固话)
			json.put("calleeNum", phoneInfoVo.getPhoneNo());
			//绑定关系保持时间 秒
			json.put("duration", phoneInfoVo.getPrDuration() * 60);
			//单次通话最长时间 分钟
			json.put("maxDuration", phoneInfoVo.getPrDuration());
			/**
			 * 选填,各参数要求请参考"AXB模式绑定接口"
			 */
			//城市码
			json.put("areaCode", "029");
			//号码池删选
			json.put("areaMatchMode", "1");
			//允许呼叫的方向
			json.put("callDirection", 0);
			//是否通话录音
			json.put("recordFlag", "true");
			//json.put("recordHintTone", "recordHintTone.wav"); //录音提示音
			//json.put("lastMinVoice", "lastMinVoice.wav"); //通话最后一分钟提示音
//         json.put("privateSms", "true"); //是否支持短信功能
			//JSONObject preVoice = new JSONObject();
			//preVoice.put("callerHintTone", "callerHintTone.wav"); //设置A拨打X号码时的通话前等待音
			//preVoice.put("calleeHintTone", "calleeHintTone.wav"); //设置B拨打X号码时的通话前等待音
			//json.put("preVoice", preVoice); //个性化通话前等待音

			String str = HuaWeiHttpUtil.sendPost(OMPAPPKEY, OMPAPPSECRET, realUrl, json.toString());
			AxbResultEntity result = JSON.parseObject(str, AxbResultEntity.class);
			logger.info("axb 结果{}" + result);
			if ("0".equals(result.getResultcode())) {
				result.setDoctorId(phoneInfoVo.getDoctorId());
				result.setDoctPhone(phoneInfoVo.getDoctPhone());
				result.setPatientPhone(phoneInfoVo.getPhoneNo());
				result.setRelationNum(result.getRelationNum().substring(3));
				result.setCreatTime(new Date());
				result.setUpTime(new Date());
				//插入绑定结果
				iAxbResultSV.insert(result);

				//如果绑定失败定时任务再绑定一次
				//调用定时任务再绑定
			} else {
				JSONObject params = new JSONObject();
				params.put("OMPAPPKEY", OMPAPPKEY);
				params.put("OMPAPPSECRET", OMPAPPSECRET);
				params.put("realUrl", realUrl);
				params.put("json", json.toString());
				BindPhoneTask bindPhoneTask = new BindPhoneTask("绑定电话任务", TimeUnit.MINUTES.toMillis(5), params);
				messageSenderSV.sendDelayTask(bindPhoneTask);
			}

			//logger.info("Response is :" + result);
		}

	}

	/***
	 * axb绑定
	 * @param orderAndFileVO
	 * @return
	 */
	@Override
	public String axbBindNumber02(OrderAndFileVO orderAndFileVO) {
		//查询绑定状态
		AxbResultEntity axbResult = iAxbResultSV.selectBindState(orderAndFileVO.getDoctPhone(), orderAndFileVO.getAppointTime());
		if (axbResult != null) {
			return axbResult.getRelationNum();
		}

		//插入通讯录关系
		InquiryOrderParam model = InquiryOrderParam.builder()
				.doctId(orderAndFileVO.getDoctId()).patientId(orderAndFileVO.getPatientId()).build();
		doctorServiceItemImpl.createAddressBook(model);

		//必填,AXB模式绑定接口访问URI
		String url = "/rest/caas/relationnumber/partners/v1.0";
		String realUrl = buildOmpUrl(url);
		// 封装JOSN请求
		JSONObject json = new JSONObject();
		//json.put("relationNum", relationNum); // X号码(关系号码)
		// A方真实号码(手机或固话)
		json.put("callerNum", "+86" + orderAndFileVO.getDoctPhone());
		// B方真实号码(手机或固话)
		json.put("calleeNum", "+86" + orderAndFileVO.getPhoneNo());
		//绑定关系保持时间 秒
		json.put("duration", orderAndFileVO.getPrDuration() * 60);
		//单次通话最长时间 分钟
		//json.put("maxDuration", orderAndFileVO.getPrDuration());
		/**
		 * 选填,各参数要求请参考"AXB模式绑定接口"
		 */
		//城市码
		json.put("areaCode", "029");
		//号码池删选
		json.put("areaMatchMode", "1");
		//允许呼叫的方向
		json.put("callDirection", 0);
		//是否通话录音
		json.put("recordFlag", "true");
		//json.put("recordHintTone", "recordHintTone.wav"); //录音提示音
		//json.put("lastMinVoice", "lastMinVoice.wav"); //通话最后一分钟提示音
//         json.put("privateSms", "true"); //是否支持短信功能
		//JSONObject preVoice = new JSONObject();
		//preVoice.put("callerHintTone", "callerHintTone.wav"); //设置A拨打X号码时的通话前等待音
		//preVoice.put("calleeHintTone", "calleeHintTone.wav"); //设置B拨打X号码时的通话前等待音
		//json.put("preVoice", preVoice); //个性化通话前等待音

		String str = HuaWeiHttpUtil.sendPost(OMPAPPKEY, OMPAPPSECRET, realUrl, json.toString());
		AxbResultEntity result = JSON.parseObject(str, AxbResultEntity.class);
		String relationNum = null;
		logger.info("axb 结果{}" + result);
		if ("0".equals(result.getResultcode())) {
			relationNum = result.getRelationNum().substring(3).trim();
			result.setIoId(orderAndFileVO.getId());
			result.setDoctorId(orderAndFileVO.getDoctId());
			result.setDoctPhone(orderAndFileVO.getDoctPhone());
			result.setPatientPhone(orderAndFileVO.getPhoneNo());
			result.setAppointTime(orderAndFileVO.getAppointTime());
			result.setRelationNum(relationNum);
			result.setCreatTime(new Date());
			result.setUpTime(new Date());
			//插入绑定结果
			iAxbResultSV.insert(result);

			//如果绑定失败定时任务再绑定一次
			//调用定时任务再绑定
			return relationNum;
		} else {
			return "01";
		}
	}

	/**
	 * Modify number a/b of the privacy relationship assigned by subscriptionId |
	 * 隐私号码AXB绑定信息修改
	 *
	 * @param subscriptionId 绑定关系ID
	 * @param callerNum      主叫号码
	 * @param calleeNum      被叫号码
	 */
	@Override
	public void axbModifyNumber(String subscriptionId, String callerNum, String calleeNum) {
		if (StringUtils.isBlank(subscriptionId)) {
			logger.info("axbModifyNumber set params error");
			return;
		}

		// 必填,AXB模式绑定信息修改接口访问URI
		String url = "/rest/caas/relationnumber/partners/v1.0";
		String realUrl = buildOmpUrl(url);

		// 封装JOSN请求
		// 绑定关系ID
		JSONObject json = new JSONObject();
		json.put("subscriptionId", subscriptionId);
		if (StringUtils.isNotBlank(callerNum)) {
			// 将A方修改为新的号码(手机或固话)
			json.put("callerNum", callerNum);
		}
		if (StringUtils.isNotBlank(calleeNum)) {
			// 将B方修改为新的号码(手机或固话)
			json.put("calleeNum", calleeNum);
		}

		/**
		 * 选填,各参数要求请参考"AXB模式绑定信息修改接口"
		 */
//         json.put("callDirection", 0); //允许呼叫的方向
//         json.put("duration", 86400); //绑定关系保持时间
//         json.put("maxDuration", 90); //单次通话最长时间
//         json.put("lastMinVoice", "lastMinVoice.wav"); //通话最后一分钟提示音
//         json.put("privateSms", "true"); //是否支持短信功能
//         JSONObject preVoice = new JSONObject();
//         preVoice.put("callerHintTone", "callerHintTone.wav"); //设置A拨打X号码时的通话前等待音
//         preVoice.put("calleeHintTone", "calleeHintTone.wav"); //设置B拨打X号码时的通话前等待音
//         json.put("preVoice", preVoice); //个性化通话前等待音

		String result = HuaWeiHttpUtil.sendPut(OMPAPPKEY, OMPAPPSECRET, realUrl, json.toString());
		logger.info("Response is :" + result);
	}

	/**
	 * 隐私号码AXB解绑
	 *
	 * @param subscriptionId 绑定关系ID
	 * @param relationNum    关系号码 都传时以subscriptionId优先
	 */
	@Override
	public void axbUnbindNumber(String subscriptionId, String relationNum) {
		if (StringUtils.isBlank(subscriptionId) && StringUtils.isBlank(relationNum)) {
			logger.info("axbUnbindNumber set params error");
			return;
		}

		// 必填,AXB模式解绑接口访问URI
		String url = "/rest/caas/relationnumber/partners/v1.0";
		String realUrl = buildOmpUrl(url);

		// 申明对象
		Map<String, Object> map = new HashMap<String, Object>();
		if (StringUtils.isNotBlank(subscriptionId)) {
			// 绑定关系ID
			map.put("subscriptionId", subscriptionId);
		}
		if (StringUtils.isNotBlank(relationNum)) {
			// X号码(关系号码)
			map.put("relationNum", relationNum);
		}

		String result = HuaWeiHttpUtil.sendDelete(OMPAPPKEY, OMPAPPSECRET, realUrl, HuaWeiHttpUtil.map2UrlEncodeString(map));
		logger.info("Response is :" + result);
	}

	/***
	 * 查询AXB绑定信息
	 * @param subscriptionId 绑定关系ID
	 * @param relationNum    关系号码 都传时以subscriptionId优先
	 */
	@Override
	public String axbQueryBindRelation(String subscriptionId, String relationNum) {
		if (StringUtils.isBlank(subscriptionId) && StringUtils.isBlank(relationNum)) {
			logger.info("axbQueryBindRelation set params error");
			return "axbQueryBindRelation set params error";
		}

		// 必填,AXB模式绑定信息查询接口访问URI
		String url = "/rest/caas/relationnumber/partners/v1.0";
		String realUrl = buildOmpUrl(url);

		// 申明对象
		Map<String, Object> map = new HashMap<String, Object>();
		if (StringUtils.isNotBlank(subscriptionId)) {
			// 绑定关系ID
			map.put("subscriptionId", subscriptionId);
		}
		if (StringUtils.isNotBlank(relationNum)) {
			// X号码(关系号码)
			map.put("relationNum", relationNum);
		}
		/**
		 * 选填,当携带了subscriptionId时无需关注如下参数
		 */
		// map.put("pageIndex", 1); //查询的分页索引,从1开始编号
		// map.put("pageSize", 20); //查询的分页大小,即每次查询返回多少条数据

		String result = HuaWeiHttpUtil.sendGet(OMPAPPKEY, OMPAPPSECRET, realUrl, HuaWeiHttpUtil.map2UrlEncodeString(map));
		logger.info("Response is :" + result);
		return result;
	}

	/**
	 * 获取录音文件下载地址
	 *
	 * @param recordDomain 录音文件存储的服务器域名
	 * @param fileName     录音文件名
	 */
	@Override
	public String axbGetRecordDownloadLink(String recordDomain, String fileName, Long currUser) throws Exception {
		if (StringUtils.isBlank(recordDomain) || StringUtils.isBlank(fileName)) {
			logger.info("axbGetRecordDownloadLink set params error");
			return "axbGetRecordDownloadLink set params error";
		}
		// 必填,AXB模式获取录音文件下载地址接口访问URI
		String url = "/rest/provision/voice/record/v1.0";
		String realUrl = buildOmpUrl(url);

		// 申明对象
		Map<String, Object> map = new HashMap<String, Object>();
		// 录音文件存储的服务器域名
		map.put("recordDomain", recordDomain);
		// 录音文件名
		map.put("fileName", fileName);
		String result = HuaWeiHttpUtil
				.sendGet(OMPAPPKEY, OMPAPPSECRET, realUrl, HuaWeiHttpUtil.map2UrlEncodeString(map));
		logger.info("Response is :" + result);

		InputStream stream = null;
		String id = null;
		try {
			stream = HttpUtil.get(result)
					.trustAllCerts()
					.trustAllHosts()
					.stream();
			//Long cuurId = 22L;
			id = iFileInforSV.uploadFile(stream, FileTypeEnum.REC,null, "axb_result", "file_info_id", "录音文件上传", currUser);
		} catch (Exception e) {
			logger.info("获取录音文件{}", e.getMessage());
		} finally {
			if (stream != null) {
				try {
					stream.close();
				} catch (IOException e) {
					logger.info("录音文件流关闭{}", e.getMessage());
				}
			}

		}
		if (StringUtils.isEmpty(id)) {
			throw new RuntimeException("手动回滚触发");
		}
		return id;
	}

	/**
	 * 终止呼叫
	 *
	 * @param sessionid 呼叫会话ID 通过"呼叫事件通知接口"获取
	 */
	@Override
	public void axbStopCall(String sessionid) {
		if (StringUtils.isBlank(sessionid)) {
			logger.info("axbStopCall set params error");
			return;
		}

		// 必填,AXB模式终止呼叫接口访问URI
		String url = "/rest/httpsessions/callStop/v2.0";
		String realUrl = buildOmpUrl(url);

		// 封装JOSN请求
		JSONObject json = new JSONObject();
		// 呼叫会话ID
		json.put("sessionid", sessionid);
		// 取值固定为"call_stop"
		json.put("signal", "call_stop");

		String result = HuaWeiHttpUtil.sendPost(OMPAPPKEY, OMPAPPSECRET, realUrl, json.toString());
		logger.info("Response is :" + result);
	}


}
